﻿// (c) Copyright slimCODE Software Inc. - www.slimcode.com
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.

using System;
using System.Collections.Generic;
using System.Text;

namespace SlimCode.SlimPasswords
{
  class ItemStrength : IComparable<ItemStrength>
  {
    public ItemStrength( LaunchableItem item )
    {
      m_item = item;
    }

    #region Item PROPERTY

    private LaunchableItem m_item;

    public LaunchableItem Item
    {
      get { return m_item; }
    }

    #endregion

    #region BestMatch PROPERTY

    private Match m_bestMatch;

    public Match BestMatch
    {
      get { return m_bestMatch; }
    }

    #endregion

    #region Strength PROPERTY

    private int m_strength;

    public int Strength
    {
      get { return m_strength; }
    }

    #endregion

    public int UpdateStrength( string command )
    {
      // We could either return the best strength or match, or even have a Match
      // expose a strength property, but I prefer keeping this state-oriented design,
      // so we can sort by the MatchStrength property, and access BestMatch only when
      // drawing.
      m_strength = 0;
      m_bestMatch = null;

      if( !m_item.Active )
        return 0;

      IList<Match> matches = Match.FindMatches( m_item.Name, command );

      if( matches != null )
      {
        foreach( Match match in matches )
        {
          int strength = match.CalculateStrength( m_item.Name );

          if( strength > m_strength )
          {
            m_strength = strength;
            m_bestMatch = match;
          }
        }
      }

      if( m_item.LastCommand.StartsWith( command, StringComparison.InvariantCultureIgnoreCase ) )
      {
        m_strength += command.Length * command.Length;

        if( command.Length == m_item.LastCommand.Length )
        {
          // Strongly enforce exact match;
          m_strength += command.Length * command.Length;
        }
      }

      return m_strength;
    }

    #region IComparable<ItemStrength> Members

    public int CompareTo( ItemStrength other )
    {
      int thisStrength = m_strength;
      int otherStrength = other.m_strength;

      if( thisStrength < otherStrength )
        return 1; // Reverse order

      if( thisStrength > otherStrength )
        return -1; // Reverse order

      return 0;
    }

    #endregion
  }
}
